package com.acme.bankapp.service.bank;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import com.acme.bankapp.domain.account.Account;
import com.acme.bankapp.domain.account.CheckingAccount;
import com.acme.bankapp.domain.client.Client;
import com.acme.bankapp.domain.client.Gender;

public class BankDataSaverService {
    public static void save(BankService bankService, File file)
	    throws IOException {
	file.createNewFile();
	if (!file.canWrite()) {
	    throw new IOException("No access to write into a file.");
	}
	List<Client> clients = bankService.getClients();
	StringBuilder strBuild = new StringBuilder();
	PrintWriter pWriter = new PrintWriter(file);
	for (Client client : clients) {
	    Account account = client.getAccount();
	    writeAccountType(strBuild, account);
	    writeBalance(strBuild, account);
	    writeOverdraft(strBuild, account);
	    writeName(strBuild, client);
	    writeGender(strBuild, client);
	    pWriter.println(strBuild.toString());
	    strBuild.delete(0, strBuild.length());
	}
	pWriter.close();
    }

    public static void save(BankService bankService, String fileName)
	    throws IOException {
	save(bankService, new File(fileName));
    }

    protected static void writeAccountType(StringBuilder strBuild,
	    Account account) {
	strBuild.append(BankDataFormat.KeysLexem.ACCOUNT_TYPE);
	strBuild.append(BankDataFormat.KEY_VALUE_DELIMER);
	if (account instanceof CheckingAccount) {
	    strBuild.append(BankDataFormat.AccountTypeValueLexem.CHECKING);
	} else {
	    strBuild.append(BankDataFormat.AccountTypeValueLexem.SAVING);
	}
	strBuild.append(BankDataFormat.PAIRS_DELIMER);
    }

    protected static void writeBalance(StringBuilder strBuild, Account account) {
	strBuild.append(BankDataFormat.KeysLexem.ACCOUNT_BALANCE);
	strBuild.append(BankDataFormat.KEY_VALUE_DELIMER);
	strBuild.append(account.getBalance());
	strBuild.append(BankDataFormat.PAIRS_DELIMER);
    }

    protected static void writeGender(StringBuilder strBuild, Client client) {
	strBuild.append(BankDataFormat.KeysLexem.CLIENT_GENDER);
	strBuild.append(BankDataFormat.KEY_VALUE_DELIMER);
	if (client.getGender().equals(Gender.MALE)) {
	    strBuild.append(BankDataFormat.GenderValueLexem.MALE);
	} else {
	    strBuild.append(BankDataFormat.GenderValueLexem.FEMALE);
	}
	strBuild.append(BankDataFormat.PAIRS_DELIMER);
    }

    protected static void writeName(StringBuilder strBuild, Client client) {
	strBuild.append(BankDataFormat.KeysLexem.CLIENT_NAME);
	strBuild.append(BankDataFormat.KEY_VALUE_DELIMER);
	strBuild.append(client.getName());
	strBuild.append(BankDataFormat.PAIRS_DELIMER);
    }

    protected static void writeOverdraft(StringBuilder strBuild, Account account) {
	if (account instanceof CheckingAccount) {
	    strBuild.append(BankDataFormat.KeysLexem.ACCOUNT_OVERDRAFT);
	    strBuild.append(BankDataFormat.KEY_VALUE_DELIMER);
	    strBuild.append(account.maximumAmountToWithdraw()
		    - account.getBalance());
	    strBuild.append(BankDataFormat.PAIRS_DELIMER);
	}
    }
}
